<?php
namespace app\common\controller;

use app\common\library\ErrorType;
use think\facade\Config;
use think\Request;
use think\Response;
use think\exception\HttpResponseException;


class ApiBase extends YuBase
{

    /**
     * 默认响应输出类型,支持json/xml
     * @var string 
     */
    protected $responseType = 'json';

    /**
     * @var array 前置操作方法列表
     */
    protected $beforeActionList = [];

    public function __construct(Request $request = null)
    {
        parent::__construct($request);
        // 前置操作方法
        if ($this->beforeActionList)
        {
            foreach ($this->beforeActionList as $method => $options)
            {
                is_numeric($method) ?
                    $this->beforeAction($options) :
                    $this->beforeAction($method, $options);
            }
        }
    }


    /**
     * 前置操作
     * @access protected
     * @param  string $method  前置操作方法名
     * @param  array  $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
     * @return void
     */
    protected function beforeAction($method, $options = [])
    {
        if (isset($options['only']))
        {
            if (is_string($options['only']))
            {
                $options['only'] = explode(',', $options['only']);
            }

            if (!in_array($this->request->action(), $options['only']))
            {
                return;
            }
        }
        elseif (isset($options['except']))
        {
            if (is_string($options['except']))
            {
                $options['except'] = explode(',', $options['except']);
            }
            if (in_array($this->request->action(), $options['except']))
            {
                return;
            }
        }

        call_user_func([$this, $method]);
    }

    public function show($data){
    	echo '<br>'.$data;
    }

    /**
     * 操作成功返回的数据
     * @param string $msg   提示信息
     * @param mixed $data   要返回的数据
     * @param int   $code   错误码，默认为1
     * @param string $type  输出类型
     * @param array $header 发送的 Header 信息
     */
    public function success($msg = '', $data = null, $code = 200, $type = null, array $header = [])
    {
        $this->result($msg, $data, $code, $type, $header);
    }

    /**
     * 操作失败返回的数据
     * @param string $msg   提示信息
     * @param mixed $data   要返回的数据
     * @param int   $code   错误码，默认为0
     * @param string $type  输出类型
     * @param array $header 发送的 Header 信息
     */
    public function error($msg = '', $data = null, $code = 0, $type = null, array $header = [])
    {
        $this->result($msg, $data, $code, $type, $header);
    }
    /**
     * 操作失败返回的数据(封装了错误提示类)
     * @param string $errorType   提示信息错误类型
     * @param mixed $data   要返回的数据
     */
    public function err($errorType='',$data=null){
        $this->error($errorType,$data,ErrorType::getCodeBy($errorType));
    }

    /**
     * 操作成功返回的数据
     * @param string $msg 提示信息
     * @param mixed $data 要返回的数据
     * @param int $code 错误码，默认为1
     * @param string $type 输出类型
     * @param array $header 发送的 Header 信息
     * @throws \think\Exception
     */
    public static function success_static($msg = '', $data = null, $code = 200, $type = null, array $header = []){
        return ApiBase::result_static($msg, $data, $code, $type, $header);
    }

    /**
     * 操作失败返回的数据(封装了错误提示类)
     * @param string $errorType 提示信息错误类型
     * @param mixed $data 要返回的数据
     * @return void
     * @throws \think\Exception
     */
    public static function err_static($errorType='',$data=null){
        return ApiBase::error_static($errorType,$data,ErrorType::getCodeBy($errorType));
    }

    /**
     * 操作失败返回的数据
     * @param string $msg 提示信息
     * @param mixed $data 要返回的数据
     * @param int $code 错误码，默认为0
     * @param string $type 输出类型
     * @param array $header 发送的 Header 信息
     * @throws \think\Exception
     */
    public static function error_static($msg = '', $data = null, $code = 0, $type = null, array $header = []){
        return ApiBase::result_static($msg, $data, $code, $type, $header);
    }

    /**
     * 返回封装后的 API 数据到客户端
     * @access protected
     * @param mixed $msg 提示信息
     * @param mixed $data 要返回的数据
     * @param int $code 错误码，默认为0
     * @param string $type 输出类型，支持json/xml/jsonp
     * @param array $header 发送的 Header 信息
     * @return void
     * @throws \think\Exception
     */
    public static function result_static($msg, $data = null, $code = 0, $type = null, array $header = []){
        $ApiBaseObj = new \app\common\controller\ApiBase();
        return $ApiBaseObj->result($msg,$data,$code,$type,$header);
    }
    /**
     * 返回封装后的 API 数据到客户端
     * @access protected
     * @param mixed  $msg    提示信息
     * @param mixed  $data   要返回的数据
     * @param int    $code   错误码，默认为0
     * @param string $type   输出类型，支持json/xml/jsonp
     * @param array  $header 发送的 Header 信息
     * @return void
     * @throws HttpResponseException
     */
    public function result($msg, $data = null, $code = 0, $type = null, array $header = [])
    {
        $dt = $this->request->server('REQUEST_TIME');
        $date= date('Y-m-d H:i:s',$dt);
        if (Config::get('app_debug')){
            $this->debugEnd();
            $date = $date.' 执行耗时：'.$this->debugTime();
        }
        $result = [
            'code' => $code,
            'msg'  => $msg,
            'time' => $date,
            'data' => $data,
        ];
        // 如果未设置类型则自动判断
        $type = $type ? $type : ($this->request->param(config('var_jsonp_handler')) ? 'jsonp' : $this->responseType);

        if (isset($header['statuscode']))
        {
            $code = $header['statuscode'];
            unset($header['statuscode']);
        }
        else
        {
            //未设置状态码,根据code值判断
            $code = $code >= 1000 || $code < 200 ? 200 : $code;
        }

        $response = Response::create($result, $type, $code)->header($header);
        throw new HttpResponseException($response);
    }

    /**
     * @title 获取登录后的UID
     * @description <br>如需登录，调用此方法鉴权，获取登录鉴权后的uid信息
     * @description <br>注解1：如果已经登录，则会获取到uid;否则会直接打印错误信息，不执行下面的代码
     * @description <br>注解2：该方法走的是缓存，不通过数据库检查
     * @description <br>注解3：如果没有token信息，需要调登录接口，重新获取token，并保存，token有效期暂定为30天
     * @author Admin ldy
     * @param name:token  type:string require:1 default:1 desc:
     * @time 2018/9/19  8:51
     * @return bool:返回false或者直接打印错误信息
     */
    protected function getUidByCheck(){
        $token = $this->request->param('token');
        $data = [
            'token' => $token,
        ];
        $validate = new \app\common\validate\User;
        if (!$validate->scene('checkToken')->check($data)) {
            $this->error($validate->getError());
        }
        $uid = $this->getUidByToken($token);
        if ($uid==false){
            $this->err(ErrorType::UN_LOGIN_OR_TOKEN_OUT_TIME);
        }else{
            //token设置有效期为30天,连续使用的人，永不过期！！
            \cache($token,$uid,60*60*24*30,'login-token');
            return $uid;
        }
    }



    protected function getLoginUserNum(){

    }

    /**
     * @title 获取简单校验后的typeid
     * @description 获取简单校验后的typeid
     * @author Admin ldy
     * @param name:typeid  type:string require:1 default:1 desc:
     * @time 2018/9/26  10:49
     * @return mixed
     */
    protected function getTypeIdByCheck(){
        $typeid = $this->request->param('typeid');
        $data = [
            'typeid' => $typeid,
        ];
        $validate = new \app\common\validate\Type;
        if (!$validate->scene('checkType')->check($data)) {
            $this->error($validate->getError());
        }
        return $typeid;
    }

    /**
     * @title 获取简单校验后的title_id
     * @description 获取简单校验后的title_id
     * @author Admin ldy
     * @param name:title_id  type:string require:1 default:1 desc:
     * @time 2018/9/26  10:49
     * @return mixed
     */
    protected function getTitleIdByCheck(){
        $title_id = $this->request->param('title_id');
        $data = [
            'title_id' => $title_id,
        ];
        $validate = new \app\common\validate\PerUrl;
        if (!$validate->scene('checkTitleId')->check($data)) {
            $this->error($validate->getError());
        }
        return $title_id;
    }

    /**
     * @title 异步执行http任务
     * @description 异步执行http任务
     * @author Admin ldy
     * @param name:$apiString  type:string require:1 default:1 desc:
     * @param name:$params  type:array require:1 default:1 desc:
     * @time 2018/9/20  14:05
     */
    protected function asynDoByUrl($apiString,$params=array()){
        $host=$this->request->host();
//        $host = $this->request->server('SERVER_NAME');
//        $apiString = '/api/yudata/yuDetail/';
        $uu = 'http://'.$host.$apiString;
        $this->asyn_do_post($uu,$params);
    }

    /**
     * @title 写入文件的测试方法
     * @description 写入文件的测试方法
     * @author Admin ldy
     * @url /api/yudata/writetxt
     * @param name:token  type:string require:1 default:1 desc:
     * @throws \HttpException
     * @throws \HttpResponseException
     * @time 2018/9/19  14:51
     */
    protected function writetxt($content){
        $token = $this->request->param('token');
        ly(array('toekn'=>$token,'con'=>$content));
        //新增公共url
//        $url = $this->request->param('u');
//        $myfile =fopen('F:\phpStudy\WWW\ayu\test\\'.time().'.txt','w');
//        $txt = "$token\n";
//        fwrite($myfile, $txt);
//        $txt = "   $content\n";
//        fwrite($myfile, $txt);
//        fclose($myfile);
    }

    /**
     * @title 检查某个参数是否为空
     * @description 检查某个参数是否为空
     * @author Admin ldy
     * @param name:$params  type:string require:1 default:1 desc:
     * @time 2018/9/26  14:39
     */
    protected function checkEmptyParams($params){
        if (empty($params)){
            $this->err(ErrorType::PARAMS_CAN_NOT_BE_EMPTY);
        }
    }


}
